package de.uniba.wiai.lspi.chord.service.impl;

/*
 * my own implementation of a doubly linked list...
 */
public class WCContainer {
	private WCNode sentinelHead;
	private WCNode sentinelTail;

	public WCContainer() {
	 sentinelHead = new WCNode();
	 sentinelHead.setValue(-1);
	 
	 sentinelTail = new WCNode();	 
	 sentinelTail.setValue(-1);
	 
	 sentinelHead.setNext(sentinelTail);
	 sentinelHead.setPrev(null);
	 
	 sentinelTail.setNext(null);
	 sentinelTail.setPrev(sentinelHead);
	}

	public void add(WCNode node){//adding to end of list
		WCNode tail = sentinelTail.getPrev();  
		tail.setNext(node);
		node.setPrev(tail); 
		node.setNext(sentinelTail);
		sentinelTail.setPrev(node); 
	}
	
	public WCNode getLast(){
		try{
			if(isEmpty())
				throw new Exception("List is empty!!"); 
		}catch(Exception e){
			return null;
		}
		return sentinelTail.getPrev();
	}

	public WCNode getFirst(){
		try{
			if(isEmpty())
				throw new Exception("List is empty!!"); 
		}catch(Exception e){
			return null;
		}
		return sentinelHead.getNext();
	}

	public WCNode getNext(WCNode n){
		WCNode next = n.getNext(); 
		try {
			if(next == sentinelTail)
				throw new Exception("No element!");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return null; 
		}
		return next;  
	}
	public boolean isEmpty(){
		return (sentinelHead.getNext() == sentinelTail); 
	}
	public WCNode getPrevious(WCNode n){
		WCNode prev = n.getPrev();  
		try {
			if(prev == sentinelHead)
				throw new Exception("No element!");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			return null; 
		}
		return prev;  
	}

	public void replaceNodeWithTail(WCNode node){
		WCNode tail = sentinelTail.getPrev(); 
		WCNode secondLast = tail.getPrev(); 
		
		if(node == secondLast){//no shifting to be done
			node.getPrev().setNext(tail);
			tail.setPrev(node.getPrev());
			return; 
		}
		
		//Left hand side
		node.getPrev().setNext(tail);
		tail.setPrev(node.getPrev());

		//right hand side
		tail.setNext(node.getNext());
		node.getNext().setPrev(tail); 

		secondLast.setNext(sentinelTail);
		sentinelTail.setPrev(secondLast);
	}
	
	public WCNode pop(){
		WCNode nodeToPop = sentinelTail.getPrev();
		nodeToPop.getPrev().setNext(sentinelTail); 
		sentinelTail.setPrev(nodeToPop.getPrev());
		return nodeToPop;
	}
	
	public int size(){
		int size =0; 
		WCNode node = sentinelHead.getNext(); 
		while(node.getValue()!= -1){
			node = node.getNext();
			size++; 
		}
		return size; 
	}
	public String toString(){
		String out = "         Fused Data: "; 
		WCNode node = sentinelHead.getNext(); 
		while(node.getValue() != -1){
			out += ((FusedEntry)node).toString() + " "; 
			node = node.getNext(); 
		}
		return out;
	}
}
